/**
 * 默认值：
 * 像函数可以声明一个参数的默认值一样，泛型同样有着默认值的设定，比如：
*/
type Factory<T = boolean> = T | number | string;


/**
 * 泛型约束：
 * 除了声明默认值以外，泛型还能做到一样函数参数做不到的事：泛型约束。
 * 也就是说，可以要求传入这个 工具类型的泛型 必须符合某些条件，否则就拒绝进行后面的逻辑。
 * 
 * 在泛型中，可以使用 extends 关键字来约束 传入的泛型参数 必须符合要求
 * 具体来说，可以分为以下几类：
 * 
 * 更精确，如 字面量类型 是对应 原始类型的子类型，
 * 即 'hanxuming' extends string，599 extends number 成立。
 * 类似的，联合类型子集 均为 联合类型的子类型，
 * 即 1、 1 | 2 是 1 | 2 | 3 | 4 的子类型。
 * 
 * 更复杂，如 { name: string } 是 {} 的子类型，
 * 因为在 {} 的基础上增加了额外的类型，
 * 基类与派生类（父类与子类）同理。
*/
type ResStatus<ResCode extends number> = ResCode extends 10000 | 10001 | 10002
  ? 'success'
  : 'failure';


type Res1 = ResStatus<10000>; // "success"
type Res2 = ResStatus<20000>; // "failure"
type Res3 = ResStatus<'10000'>; // 类型“string”不满足约束“number”。

/**
 * 同时使用 默认值 与 泛型约束
*/
type ResStatusA<ResCode extends number = 10000> = ResCode extends 10000 | 10001 | 10002
  ? 'success'
  : 'failure';
type Res4 = ResStatusA; // "success"

/**
 * 在 TypeScript 中，泛型参数存在默认约束（在下面的函数泛型、Class 泛型中也是）。
 * 这个默认约束值在 TS 3.9 版本以前是 any，
 * 而在 3.9 版本以后则为 unknown。
 * 
 * 在 TypeScript ESLint 中，
 * 可以使用 no-unnecessary-type-constraint 规则，
 * 来避免代码中声明了与默认约束相同的泛型约束。
*/

//export {}：解决“无法重新声明块范围变量”错误提示问题
export { }